package com.youdianstar.app.ui

import android.Manifest
import android.content.Intent
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.view.View

import com.youdianstar.app.R
import com.youdianstar.app.BR
import com.youdianstar.app.common.BisType
import com.youdianstar.app.common.Extra
import com.youdianstar.app.common.base.BaseActivity
import com.youdianstar.app.common.network.BaseApiResultObserver
import com.youdianstar.app.common.util.LogUtil
import com.youdianstar.app.common.util.StrUtil
import com.youdianstar.app.common.util.dialog.DialogUtil
import com.youdianstar.app.common.ex.setThrottleListener
import com.youdianstar.app.databinding.ActivityScanBinding
import com.youdianstar.app.entity.ReqStationPlan
import com.youdianstar.app.util.ScanHelperEx

import com.gyf.immersionbar.ImmersionBar
import com.youdianstar.app.entity.RentCheck
import com.youdianstar.app.util.DataAppManager
import com.youdianstar.app.util.DataHelperEx
import com.youdianstar.app.common.auko.startActivity
import com.youdianstar.app.ui.reward.RewardHomeActivity
import org.koin.androidx.viewmodel.ext.android.viewModel

class ScanActivity : BaseActivity<ActivityScanBinding, ScanViewModel>() {

    override fun layoutId(): Int = R.layout.activity_scan

    override fun initVariableId(): Int = BR.viewModel

    override fun initViewModel(): ScanViewModel {
        val model: ScanViewModel by viewModel()
        return model
    }

    private var scanHelper: ScanHelperEx? = null
    private val mHandler = Handler(Looper.myLooper()!!)

    //业务类型 0:租借扫码 1:上报  11:品牌选择 12:品牌添加 16:置换PB 17:购买PB
    private var bisType = -1

    private var rentSno: String = ""
    private var rentSnoUrl: String = ""

    //租借失败原因: checkRentOrNot 接口
    private var failedReason: Int = 0

    override fun initData() {
        super.initData()
        ImmersionBar.with(this).titleBarMarginTop(mBinding.back).statusBarDarkFont(true).init()
        if (bisType == -1)
            bisType = intent.getIntExtra(Extra.IT_TYPE, BisType.Scan_Rent)

        setScanLayout()

        scanHelper = ScanHelperEx().setOnResultCallback(object : ScanHelperEx.OnResultCallback {
            override fun onResultCallback(result: String?) {
                LogUtil.d("---scan result:$result")
                result?.let { text ->
                    scanHelper?.stopScan()
                    if (bisType == BisType.Scan_ChargingCard){
                        checkRewardCodeBis(result)
                    }else{
//                        if (!text.contains("id") and !text.contains("sno")){
//                            mHandler.removeCallbacksAndMessages(null)
//                            mHandler.postDelayed({
//                                scanHelper?.reStartScan()
//                            },1000L)
//                            return
//                        }
                        // 提取设备ID - 支持多种URL格式
                        val deviceId = extractDeviceIdFromText(text)
                        
                        if (StrUtil.isEmpty(deviceId) || !StrUtil.isLetterDigit(deviceId)) {
                            toastShow(getString(R.string.toast_validQRCode))
                            mHandler.removeCallbacksAndMessages(null)
                            mHandler.postDelayed({
                                scanHelper?.reStartScan()
                            }, 1000L)
                            return
                        }
                        
                        // 直接跳转到扫码结果页，不做任何接口调用
                        startActivity<ScanResultActivity>(Extra.IT_MSG to deviceId)
                        finish()
                    }
                }
            }
        })
            .init(this, mBinding.previewView, mBinding.viewfinderView, mBinding.ivFlashlight)

        initCameraPermission()
    }

    private fun setScanLayout() {
        if (bisType == BisType.Scan_Rent) {
            failedReason = intent.getIntExtra(Extra.IT_REASON, 0)
            mBinding.clSnoInput.visibility = View.VISIBLE
        }else if (bisType == BisType.Scan_Report || bisType == BisType.Scan_ChargingCard){
            mBinding.clSnoInput.visibility = View.INVISIBLE
        }
    }

    override fun onResume() {
        super.onResume()
        scanHelper?.let {
            if (it.isVerifyData)
                it.reStartScan()
        }
        mViewModel.isReqRuler = false
        DataAppManager.instance.rentScanTag = false
    }

    override fun initClickEvent() {
        mBinding.back.setThrottleListener {
            finish()
        }
        mBinding.btnInput.setThrottleListener {
            val sno = mViewModel.snoObField.get()
            sno?.let {
                if (StrUtil.isEmpty(it)) {
                    toastShow(getString(R.string.toast_enterStationID))
                    return@let
                }
                if (!StrUtil.isLetterDigit(it)) {
                    toastShow(getString(R.string.toast_validQRCode))
                    return@let
                }
                // 直接跳转到扫码结果页，传递设备ID
                startActivity<ScanResultActivity>(Extra.IT_MSG to it)
                finish()
            }
        }
    }

    override fun initLiveObserver() {
        super.initLiveObserver()
        // 扫码页不做任何业务接口调用，直接跳转到结果页
        // 以下代码已废弃，只保留基本结构
        /*
        mViewModel.planResultLiveData.observe(this, object : BaseApiResultObserver<ReqStationPlan>(false) {
                override fun onDataResult(data: ReqStationPlan?) {
                    super.onDataResult(data)
                    mViewModel.isReqRuler = false
                    dismissDialog()
                    data?.let {
                        mViewModel.planNetDataFiled.set(it)
                        //0-机柜可用 1-充电宝电量过低 2-项目信息
                        when (it.code) {
                            1 -> {
                                var bc = 0
                                it.maxBc?.let { max ->
                                    bc = max
                                }
                                showLowPowerDialog("$bc%")
                            }
                            2 -> {
                                toastShow("Error QR code!")
                                mHandler.postDelayed({
                                    scanHelper?.reStartScan()
                                },1000L)
                            }
                            else -> {
                                //先检查用户是否可租借,再提示计费规则
                                mViewModel.checkRentOrNot(rentSno)
                            }
                        }
                    }
                }

                override fun onNetError(code: Int, e: String?) {
                    super.onNetError(code, e)
                    mViewModel.isReqRuler = false
                    dismissDialog()
                    toastShow(e)
                    mHandler.postDelayed({
                        scanHelper?.reStartScan()
                    },3000L)
                }
            })

        /*租借条件检查*/
        mViewModel.rentCheckResultData.observe(this, object : BaseApiResultObserver<RentCheck>(false) {
            override fun onDataResult(data: RentCheck?) {
                super.onDataResult(data)
                dismissDialog()
                data?.let { rs->
                    // 0:可以租借 1：不满足租借条件 2：有未支付订单 3：子账号有未完成订单 4：租借订单已达上限
                    // 5：绑定的卡还有即将过期 6:主账号有未支付订单 7:主账号绑定的卡过期或异常状态 8：主账号绑定的卡即将过期 9:调查中的订单已达到上限
                    when (rs.rentOrNot) {
                        0 -> {
                            showPricePlan(0)
                        }
                        1 -> {
                            showPricePlan(1)
//                            DataAppManager.instance.rentScanTag = true
//                            startActivity<WalletActivity>()//跳转钱包页 (预授权放弃这个逻辑)
                        }
                        2 -> {
                            showRentCondition(msg = getString(R.string.Dialog_HomeRent_Message2),
                                confirmText = getString(R.string.home_gotoPay),
                                confirmAction = {
                                    rs.orderNo?.let { orderNo->
                                        startActivity<OrderDetailActivity>(Extra.IT_ORDERNO to orderNo)
                                    }
                                },
                                isShowLeft = true
                            )
                        }
                        4 -> {
                            toastShow(getString(R.string.Dialog_HomeRent_Message4))
                            mHandler.postDelayed({
                                scanHelper?.reStartScan()
                            },1000L)
                        }

                        7 -> {
                            //卡快过期
                            toastShow(getString(R.string.Dialog_HomeRent_Message7))
                            mHandler.postDelayed({
                                scanHelper?.reStartScan()
                            },1000L)
                        }
                        9-> {
                            toastShow(getString(R.string.Dialog_HomeRent_Message9))
                            mHandler.postDelayed({
                                scanHelper?.reStartScan()
                            },1000L)
                        }
                        10->{
                            showPricePlan(0)//有押金
                        }
                        11 ->{
                            showPricePlan(0)//白名单
                        }
                        else -> {
                            showPricePlan(1)
                        }
                    }
                }
            }

            override fun onNetError(code: Int, e: String?) {
                super.onNetError(code, e)
                dismissDialog()
                toastShow(e)
                mHandler.postDelayed({
                    scanHelper?.reStartScan()
                },1000L)
            }
        })

        /*充电卡兑换*/
        mViewModel.redeemChargingCardResultData.observe(this,object : BaseApiResultObserver<Any>(true){
            override fun onDataResult(data: Any?) {
                super.onDataResult(data)
                //兑换结果
                mHandler.postDelayed({
                    dismissDialog()
                    //1-优惠券 2-优惠码 3-充电卡
                    when(mViewModel.rewardQRType){
                        1 ->{
                            toastShow(getString(R.string.charge_couponTips))
                            startActivity<RewardHomeActivity>(Extra.IT_TYPE to 0)
                        }
                        2-> {
                            toastShow(getString(R.string.charge_promoTips))
                            startActivity<RewardHomeActivity>(Extra.IT_TYPE to 1)
                        }
                        else -> {
                            toastShow(getString(R.string.charge_cardTips))
//                            if (bisType == BisType.Scan_ChargingCard)
//                                DataAppManager.instance.chargingUpdateTag = true
//                            else{
//                                startActivity<ChargeListActivity>()
//                            }
                        }
                    }
                    finish()
                },2000L)
            }

            override fun onNetError(code: Int, e: String?) {
                super.onNetError(code, e)
                dismissDialog()
                toastShow(e)
            }
        })
        */
    }


    /**
     * 扫码处理--判断扫码业务 (已废弃，扫码页只做跳转)
     *
     * @param sno 机柜编号
     * @param qrContent 二维吗内容
     */
    private fun onBisActionCheck(sno: String, qrContent: String) {
        rentSno = sno
        rentSnoUrl = qrContent
        when (bisType) {
            BisType.Scan_Rent -> {
                scanHelper?.setVerify(true)
                mViewModel.getPricePlan(sno, qrContent)
            }
            else -> {
                val intent = Intent()
                intent.putExtra(Extra.IT_SNO, sno)
                setResult(RESULT_OK, intent)
                finish()
            }
        }
    }

    /**
     * 提示计费规则
     *
     * @param status 0:可以租借 1：未交押金或没有绑定银行卡
     */
    private fun showPricePlan(status:Int) {
        mViewModel.planNetDataFiled.get()?.let { req ->
            if (null==req.billing){
                toastShow(getString(R.string.toast_dataError))
                return@let
            }
            req.billing.let { plan ->
                val planText = DataHelperEx.pricePlanTx(this@ScanActivity,plan)
                val branchName = req.branchName ?: ""
                mHandler.postDelayed({
                    //跳转计费规则
                    startActivity<RentPlanActivity>(
                        Extra.IT_SNO to rentSno,
                        Extra.IT_TYPE to status,
                        Extra.IT_AMOUNT to req.preAuthAmount,
                        Extra.IT_PREAMOUNT to req.prepaymentAmount,
                        Extra.IT_DATA to planText,
                        Extra.IT_MSG to branchName)
                    this.finish()
                }, 300L)
            }
        }
    }

    /**
     * 租借条件-失败原因提示
     *
     * @param msg 提示内容
     */
    private fun showRentCondition(
        titleText: String? = null, msg: String,
        confirmText: String? = null, confirmAction: (() -> Unit) = { }, isShowLeft: Boolean
    ) {
        DialogUtil.instance.showNotifyDialog(this, title = titleText ?: getString(R.string.public_notice), msg = msg,
            leftAction = {

            },
            left = getString(R.string.public_cancel),
            rightAction = confirmAction,
            right = confirmText ?: getString(R.string.home_confirm),
            isShowLeft = isShowLeft, isShowRight = true
        )
    }

    /**
     * 低电量提示
     *
     * @param powerTx 当前电量
     */
    private fun showLowPowerDialog(powerTx: String) {
        LogUtil.d("----bc Str = $powerTx")
        val lowpowerTx : String  = String.format(getString(R.string.rent_lowPower_notify), powerTx)
        DialogUtil.instance.showNotifyDialog(this,
            title = getString(R.string.rent_lowPower), msg = lowpowerTx,
            leftAction = {

            }, rightAction = {
                mViewModel.checkRentOrNot(rentSno)
            }, left = getString(R.string.public_notNow), right = getString(R.string.public_yes)
        )
    }

    /**
     * 从扫码文本中提取设备ID
     * 支持多种格式：
     * - https://dev.youdian.asia/sw/app/r/scan.html?id=10000269
     * - id=10000269
     * - deviceId=10000269
     * - sno=10000269
     * - 纯数字/字母组合
     */
    private fun extractDeviceIdFromText(text: String): String {
        return try {
            when {
                // 处理完整URL格式：https://dev.youdian.asia/sw/app/r/scan.html?id=10000269
                text.contains("scan.html?id=") -> {
                    val idIndex = text.indexOf("scan.html?id=") + 13
                    val idValue = text.substring(idIndex)
                    // 移除可能的额外参数
                    if (idValue.contains("&")) {
                        idValue.substring(0, idValue.indexOf("&"))
                    } else {
                        idValue
                    }
                }
                // 处理 id= 格式
                text.contains("id=") -> {
                    val idIndex = text.lastIndexOf("id=") + 3
                    val idValue = text.substring(idIndex)
                    if (idValue.contains("&")) {
                        idValue.substring(0, idValue.indexOf("&"))
                    } else {
                        idValue
                    }
                }
                // 处理 deviceId= 格式
                text.contains("deviceId=") -> {
                    val idIndex = text.lastIndexOf("deviceId=") + 9
                    val idValue = text.substring(idIndex)
                    if (idValue.contains("&")) {
                        idValue.substring(0, idValue.indexOf("&"))
                    } else {
                        idValue
                    }
                }
                // 处理 sno= 格式
                text.contains("sno=") -> {
                    val idIndex = text.lastIndexOf("sno=") + 4
                    val idValue = text.substring(idIndex)
                    if (idValue.contains("&")) {
                        idValue.substring(0, idValue.indexOf("&"))
                    } else {
                        idValue
                    }
                }
                // 处理纯路径格式，取最后一个路径段
                text.contains("/") -> {
                    text.substring(text.lastIndexOf("/") + 1)
                }
                // 直接返回原文本
                else -> text
            }
        } catch (e: Exception) {
            LogUtil.e("提取设备ID失败", e)
            text
        }
    }

    /**
     * 判断处理奖励扫码
     * @param qrContent 二维码内容/一般是Uri string
     */
    private fun checkRewardCodeBis(qrContent:String){
        try {
            val rewardUri :Uri = Uri.parse(qrContent)
            if (rewardUri.pathSegments!=null){
                //Scan Reward Code ,1-优惠券 2-优惠码 3-充电卡
                val rewardType :String = rewardUri.getQueryParameter("type")?:""
                val rewardCode :String = rewardUri.getQueryParameter("code")?:""
                if (bisType == BisType.Scan_ChargingCard && rewardType.toInt() != 3){
                    toastShow(getString(R.string.toast_validQRCode))
                    return
                }
                mViewModel.redeemRewardCode(rewardType.toInt(),rewardCode)
            }else{
                scanHelper?.reStartScan()
            }
        }catch (_:Exception){
            toastShow(getString(R.string.toast_validQRCode))
            mHandler.removeCallbacksAndMessages(null)
            mHandler.postDelayed({
                scanHelper?.reStartScan()
            },1000L)
        }
    }

    override fun onPermissionsGranted(requestCode: Int, perms: List<String>) {
        super.onPermissionsGranted(requestCode, perms)
        if (requestCode == REQUEST_PERMISSION_CODE)
            scanHelper?.startScan()
    }

    private fun initCameraPermission() {
        requestPermission(getString(R.string.Camera_Permission_Tip), Manifest.permission.CAMERA,
            granted = {
                LogUtil.i("--is-camera perms")
                scanHelper?.startScan()
            })
    }

    override fun onDestroy() {
        mHandler.removeCallbacksAndMessages(null)
        scanHelper?.releaseCamera()
        super.onDestroy()
    }

}